import axios, { AxiosResponse,AxiosInstance, AxiosRequestConfig } from "axios";
import { useUserStore } from '/@/store/modules/user';
import { message } from 'ant-design-vue';
import { router } from "/@/router";

export interface IMAxios {
  request<T = any, D = any>(config: AxiosRequestConfig<D>): Promise<T>;
  get<T = any, D = any>(url: string, config?: AxiosRequestConfig<D>): Promise<T>;
  delete<T = any, D = any>(url: string, config?: AxiosRequestConfig<D>): Promise<T>;
  head<T = any, D = any>(url: string, config?: AxiosRequestConfig<D>): Promise<T>;
  options<T = any, D = any>(url: string, config?: AxiosRequestConfig<D>): Promise<T>;
  post<T = any, D = any>(url: string, data?: D, config?: AxiosRequestConfig<D>): Promise<T>;
  put<T = any, D = any>(url: string, data?: D, config?: AxiosRequestConfig<D>): Promise<T>;
  patch<T = any, D = any>(url: string, data?: D, config?: AxiosRequestConfig<D>): Promise<T>;
  postForm<T = any, D = any>(url: string, data?: D, config?: AxiosRequestConfig<D>): Promise<T>;
  putForm<T = any, D = any>(url: string, data?: D, config?: AxiosRequestConfig<D>): Promise<T>;
  patchForm<T = any, D = any>(url: string, data?: D, config?: AxiosRequestConfig<D>): Promise<T>;
  upload<T = any, D = any>(url: string, data?: D, config?: AxiosRequestConfig<D>): Promise<T>;
}
export interface MAxiosRequestConfig<D = any> extends AxiosRequestConfig<D>{
  errorMessageMode?: string, // 错误消息提示方式，none=>无 | 默认message=>ant design message
  ignoreToken?: boolean, // 是否忽略token
}
export class MAxios implements IMAxios {
  instance: AxiosInstance;
  constructor({baseURL, timeout }: { baseURL?: string, timeout?: number }) {
    this.instance = axios.create({
      baseURL: baseURL,
      timeout: timeout,
    })
    this.instance.interceptors.request.use((config: MAxiosRequestConfig)=>{
      if(config.ignoreToken !== true) {
        const userStore = useUserStore()
        const token = userStore.getToken
        config.headers = {
          ...config.headers,
          Authorization: 'Bearer '+token,
          // 这里的tokenkey提供给apifox使用，后续再根据apifox条件追加
          token: 'Bearer '+token,
        }
      }
      return config;
    })
  }
  upload<T = any, D = any>(url: string, data?: D | undefined, config?: AxiosRequestConfig<D> | undefined): Promise<T> {
    return this.request({
      method: 'post',
      headers: {
        'Content-Type': 'multipart/form-data'
      },
      url,
      data,
      ...config
    })
  }
  request<T = any,D = any>(config: MAxiosRequestConfig<D>): Promise<T> {
    return new Promise<T>((resolve, reject) => {
      this.instance.request(config).then((response: AxiosResponse) => {
        const code = response.data.code
        if(code !== 0) {
          if(config.errorMessageMode != 'none'){
            message.error(response.data.msg || '接口异常')
          }
          // TOKEN_EXPIRE(10000002, "token不存在或已过期"),
          //NOT_AUTH(10000003,"您没有权限访问，请联系管理员！")
          if(code == 10000002 ) {
            // 清理本地token等信息
            const userStore = useUserStore()
            userStore.clearUserCache()
            // 重定向到登录页
            router.push({
              name: 'login'
            })
          } else if(code == 10000003) {

          }
        }
        resolve(response.data)
      }).catch(e => {
        reject(e)
      })
    })
  }
  get<T = any, D = any>(url: string, config?: MAxiosRequestConfig<D> | undefined): Promise<T> {
    return this.request({
      method: 'get',
      url,
      ...config
    })
  }
  delete<T = any, D = any>(url: string, config?: MAxiosRequestConfig<D> | undefined): Promise<T> {
    return this.request({
      method: 'delete',
      url,
      ...config
    })
  }
  head<T = any, D = any>(url: string, config?: MAxiosRequestConfig<D> | undefined): Promise<T> {
    return this.request({
      method: 'head',
      url,
      ...config
    })
  }
  options<T = any, D = any>(url: string, config?: MAxiosRequestConfig<D> | undefined): Promise<T> {
    return this.request({
      method: 'options',
      url,
      ...config
    })
  }
  post<T = any, D = any>(url: string, data?: D | undefined, config?: MAxiosRequestConfig<D> | undefined): Promise<T> {
    return this.request({
      method: 'post',
      url,
      data,
      ...config
    })
  }
  put<T = any, D = any>(url: string, data?: D | undefined, config?: MAxiosRequestConfig<D> | undefined): Promise<T> {
    return this.request({
      method: 'put',
      url,
      data,
      ...config
    })
  }
  patch<T = any, D = any>(url: string, data?: D | undefined, config?: MAxiosRequestConfig<D> | undefined): Promise<T> {
    return this.request({
      method: 'patch',
      url,
      data,
      ...config
    })
  }
  postForm<T = any, D = any>(url: string, data?: D | undefined, config?: MAxiosRequestConfig<D> | undefined): Promise<T> {
    return this.request({
      method: 'post',
      headers: {
        'Content-Type': 'application/x-www-form-urlencode; charset=UTF-8'
      },
      url,
      data,
      ...config
    })
  }
  putForm<T = any, D = any>(url: string, data?: D | undefined, config?: MAxiosRequestConfig<D> | undefined): Promise<T> {
    return this.request({
      method: 'put',
      headers: {
        'Content-Type': 'application/x-www-form-urlencode; charset=UTF-8'
      },
      url,
      data,
      ...config
    })
  }
  patchForm<T = any, D = any>(url: string, data?: D | undefined, config?: MAxiosRequestConfig<D> | undefined): Promise<T> {
    return this.request({
      method: 'patch',
      headers: {
        'Content-Type': 'application/x-www-form-urlencode; charset=UTF-8'
      },
      url,
      data,
      ...config
    })
  }
}
const instance = new MAxios({
  baseURL: import.meta.env.VITE_APP_API,
  timeout: 15000
})
export default instance